package com.ssm.security.authorization;

import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.ssm.security.JWTUserDetails;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

import java.util.Collection;
import java.util.Iterator;


/**
 * Created by wchen on 2017/7/13.
 */
public class MyAccessDecisionManager implements AccessDecisionManager {

    protected final Log logger = LogFactory.getLog(this.getClass());
    /**
     * 此方法是为了判定用户请求的url 是否在权限表中，如果在权限表中，则返回给 decide 方法，用来判定用户是否有此权限。如果不在权限表中则放行。
     * object 包含客户端发起的请求的requset信息，可转换为 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
     * authentication 是CustomUserService中循环添加到 GrantedAuthority 对象中的权限信息集合.
     * @param authentication
     * @param object
     * @param configAttributes
     * @throws AccessDeniedException
     * @throws InsufficientAuthenticationException
     */
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
        String username = "anonymousUser";
        if (authentication.getPrincipal() !=null && !authentication.getPrincipal().equals("anonymousUser")){
            JWTUserDetails jwtUserDetails = (JWTUserDetails) authentication.getPrincipal();
            username = jwtUserDetails.getUsername();
        }
        logger.info("user "+ "'" +username+ "'" +"check user URL role");
        if(configAttributes == null){
            logger.info("user "+ "'" +username+ "'" +" Attributes is null");
            return ;
        }

        Iterator<ConfigAttribute> ite=configAttributes.iterator();
        while(ite.hasNext()){
            ConfigAttribute ca=ite.next();
            String needRole=((SecurityConfig)ca).getAttribute();
            for(GrantedAuthority ga:authentication.getAuthorities()){
                if(needRole.equals(ga.getAuthority())){  //ga is user's role.
                    logger.info("user "+ "'" +username+ "'" + " math role success with: "+ga.getAuthority());
                    return;
                }
            }
        }
        logger.warn("user "+ "'" +username+ "'" + " no right request " +object.getClass());
        throw new AccessDeniedException("no right");
    }


    @Override
    public boolean supports(ConfigAttribute attribute) {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }


}
